{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "00545faa-0423-4506-a7eb-b3aa36558b5e",
   "metadata": {},
   "source": [
    "# 第十一节、分组聚合"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "b26a129b-23ed-4a46-b9b2-4e33cb94acc0",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e388c8b9-620b-4cf3-b80a-a1484ea92e67",
   "metadata": {},
   "source": [
    "## （1）分组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "67245f66-9c2e-4eac-ad8b-a9f30fd17985",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sex</th>\n",
       "      <th>class</th>\n",
       "      <th>Python</th>\n",
       "      <th>Keras</th>\n",
       "      <th>Tensorflow</th>\n",
       "      <th>Java</th>\n",
       "      <th>C++</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>8</td>\n",
       "      <td>126</td>\n",
       "      <td>149</td>\n",
       "      <td>137</td>\n",
       "      <td>129</td>\n",
       "      <td>126</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0</td>\n",
       "      <td>3</td>\n",
       "      <td>87</td>\n",
       "      <td>138</td>\n",
       "      <td>76</td>\n",
       "      <td>140</td>\n",
       "      <td>124</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0</td>\n",
       "      <td>3</td>\n",
       "      <td>9</td>\n",
       "      <td>33</td>\n",
       "      <td>136</td>\n",
       "      <td>138</td>\n",
       "      <td>12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0</td>\n",
       "      <td>4</td>\n",
       "      <td>115</td>\n",
       "      <td>108</td>\n",
       "      <td>63</td>\n",
       "      <td>5</td>\n",
       "      <td>85</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>5</td>\n",
       "      <td>116</td>\n",
       "      <td>20</td>\n",
       "      <td>108</td>\n",
       "      <td>0</td>\n",
       "      <td>120</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>295</th>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>67</td>\n",
       "      <td>60</td>\n",
       "      <td>62</td>\n",
       "      <td>51</td>\n",
       "      <td>129</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>296</th>\n",
       "      <td>1</td>\n",
       "      <td>8</td>\n",
       "      <td>129</td>\n",
       "      <td>139</td>\n",
       "      <td>47</td>\n",
       "      <td>124</td>\n",
       "      <td>143</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>297</th>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>34</td>\n",
       "      <td>27</td>\n",
       "      <td>126</td>\n",
       "      <td>124</td>\n",
       "      <td>17</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>298</th>\n",
       "      <td>0</td>\n",
       "      <td>4</td>\n",
       "      <td>11</td>\n",
       "      <td>94</td>\n",
       "      <td>126</td>\n",
       "      <td>69</td>\n",
       "      <td>131</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>299</th>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>23</td>\n",
       "      <td>22</td>\n",
       "      <td>146</td>\n",
       "      <td>128</td>\n",
       "      <td>46</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>300 rows × 7 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "     sex  class  Python  Keras  Tensorflow  Java  C++\n",
       "0      0      8     126    149         137   129  126\n",
       "1      0      3      87    138          76   140  124\n",
       "2      0      3       9     33         136   138   12\n",
       "3      0      4     115    108          63     5   85\n",
       "4      0      5     116     20         108     0  120\n",
       "..   ...    ...     ...    ...         ...   ...  ...\n",
       "295    0      2      67     60          62    51  129\n",
       "296    1      8     129    139          47   124  143\n",
       "297    0      1      34     27         126   124   17\n",
       "298    0      4      11     94         126    69  131\n",
       "299    1      2      23     22         146   128   46\n",
       "\n",
       "[300 rows x 7 columns]"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 准备数据\n",
    "df = pd.DataFrame(\n",
    "    data = {\n",
    "        'sex': np.random.randint(0,2,size=300),      # 0男，1女\n",
    "        'class': np.random.randint(1,9,size=300),    #1~8八个班\n",
    "        'Python': np.random.randint(0,151,size=300), #Python成绩\n",
    "        'Keras': np.random.randint(0,151,size=300),   #Keras成绩\n",
    "        'Tensorflow': np.random.randint(0,151,size=300),\n",
    "        'Java': np.random.randint(0,151,size=300),\n",
    "        'C++': np.random.randint(0,151,size=300)\n",
    "        }\n",
    ")\n",
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "df0914d2-8ce5-49e3-b3f5-a2e5a09ece10",
   "metadata": {},
   "outputs": [],
   "source": [
    "df['sex'] = df['sex'].map({0: '男', 1: '女'})   # 将0，1映射成男和女"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "da6a9957-def0-4280-be9a-3fd4b30f749a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sex</th>\n",
       "      <th>class</th>\n",
       "      <th>Python</th>\n",
       "      <th>Keras</th>\n",
       "      <th>Tensorflow</th>\n",
       "      <th>Java</th>\n",
       "      <th>C++</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>男</td>\n",
       "      <td>8</td>\n",
       "      <td>126</td>\n",
       "      <td>149</td>\n",
       "      <td>137</td>\n",
       "      <td>129</td>\n",
       "      <td>126</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>男</td>\n",
       "      <td>3</td>\n",
       "      <td>87</td>\n",
       "      <td>138</td>\n",
       "      <td>76</td>\n",
       "      <td>140</td>\n",
       "      <td>124</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>男</td>\n",
       "      <td>3</td>\n",
       "      <td>9</td>\n",
       "      <td>33</td>\n",
       "      <td>136</td>\n",
       "      <td>138</td>\n",
       "      <td>12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>男</td>\n",
       "      <td>4</td>\n",
       "      <td>115</td>\n",
       "      <td>108</td>\n",
       "      <td>63</td>\n",
       "      <td>5</td>\n",
       "      <td>85</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>男</td>\n",
       "      <td>5</td>\n",
       "      <td>116</td>\n",
       "      <td>20</td>\n",
       "      <td>108</td>\n",
       "      <td>0</td>\n",
       "      <td>120</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>295</th>\n",
       "      <td>男</td>\n",
       "      <td>2</td>\n",
       "      <td>67</td>\n",
       "      <td>60</td>\n",
       "      <td>62</td>\n",
       "      <td>51</td>\n",
       "      <td>129</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>296</th>\n",
       "      <td>女</td>\n",
       "      <td>8</td>\n",
       "      <td>129</td>\n",
       "      <td>139</td>\n",
       "      <td>47</td>\n",
       "      <td>124</td>\n",
       "      <td>143</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>297</th>\n",
       "      <td>男</td>\n",
       "      <td>1</td>\n",
       "      <td>34</td>\n",
       "      <td>27</td>\n",
       "      <td>126</td>\n",
       "      <td>124</td>\n",
       "      <td>17</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>298</th>\n",
       "      <td>男</td>\n",
       "      <td>4</td>\n",
       "      <td>11</td>\n",
       "      <td>94</td>\n",
       "      <td>126</td>\n",
       "      <td>69</td>\n",
       "      <td>131</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>299</th>\n",
       "      <td>女</td>\n",
       "      <td>2</td>\n",
       "      <td>23</td>\n",
       "      <td>22</td>\n",
       "      <td>146</td>\n",
       "      <td>128</td>\n",
       "      <td>46</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>300 rows × 7 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "    sex  class  Python  Keras  Tensorflow  Java  C++\n",
       "0     男      8     126    149         137   129  126\n",
       "1     男      3      87    138          76   140  124\n",
       "2     男      3       9     33         136   138   12\n",
       "3     男      4     115    108          63     5   85\n",
       "4     男      5     116     20         108     0  120\n",
       "..   ..    ...     ...    ...         ...   ...  ...\n",
       "295   男      2      67     60          62    51  129\n",
       "296   女      8     129    139          47   124  143\n",
       "297   男      1      34     27         126   124   17\n",
       "298   男      4      11     94         126    69  131\n",
       "299   女      2      23     22         146   128   46\n",
       "\n",
       "[300 rows x 7 columns]"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f2045053-1e52-4b71-b96f-420ce8cda6ed",
   "metadata": {},
   "source": [
    "分组后的结果是一个可迭代对象"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "72fd2e78-9927-4792-90cd-8f5379518282",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 先分组再获取数据\n",
    "g = df.groupby(by='sex')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "a0ff415e-3271-40d0-8043-0d447dd231c7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<pandas.core.groupby.generic.DataFrameGroupBy object at 0x000002007FDDF970>"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "g"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "8fc7037b-561d-4cd5-a43f-d70dcd95e4bb",
   "metadata": {},
   "outputs": [],
   "source": [
    "g = df.groupby(by='sex')[['Python', 'Java']]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "32c5fbb1-8d99-4968-a7d6-08f8e09444c8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<pandas.core.groupby.generic.DataFrameGroupBy object at 0x000002007F0EFE80>"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "g"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "107d7832-c9c2-4848-9f21-63d2cccc401e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('女',      Python  Java\n",
      "5       101    54\n",
      "6        38    99\n",
      "8        49    54\n",
      "9       148   120\n",
      "10       51    59\n",
      "..      ...   ...\n",
      "286      53     1\n",
      "287     126     5\n",
      "288     120    17\n",
      "296     129   124\n",
      "299      23   128\n",
      "\n",
      "[158 rows x 2 columns])\n",
      "('男',      Python  Java\n",
      "0       126   129\n",
      "1        87   140\n",
      "2         9   138\n",
      "3       115     5\n",
      "4       116     0\n",
      "..      ...   ...\n",
      "293      92    58\n",
      "294     144   142\n",
      "295      67    51\n",
      "297      34   124\n",
      "298      11    69\n",
      "\n",
      "[142 rows x 2 columns])\n"
     ]
    }
   ],
   "source": [
    "for item in g:\n",
    "    print(item)  # 是一个个元组(name, data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "62c1b936-d3aa-4012-9c2a-cd25a396602e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "组名： 女\n",
      "数据：      Python  Java\n",
      "5       101    54\n",
      "6        38    99\n",
      "8        49    54\n",
      "9       148   120\n",
      "10       51    59\n",
      "..      ...   ...\n",
      "286      53     1\n",
      "287     126     5\n",
      "288     120    17\n",
      "296     129   124\n",
      "299      23   128\n",
      "\n",
      "[158 rows x 2 columns]\n",
      "组名： 男\n",
      "数据：      Python  Java\n",
      "0       126   129\n",
      "1        87   140\n",
      "2         9   138\n",
      "3       115     5\n",
      "4       116     0\n",
      "..      ...   ...\n",
      "293      92    58\n",
      "294     144   142\n",
      "295      67    51\n",
      "297      34   124\n",
      "298      11    69\n",
      "\n",
      "[142 rows x 2 columns]\n"
     ]
    }
   ],
   "source": [
    "for name, data in g:\n",
    "    print('组名：', name)\n",
    "    print('数据：', data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "c4a8b416-e6ee-4233-a3c0-706fc1c2a1cc",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 多分组\n",
    "g = df.groupby(by=['class', 'sex'])[['Python']]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "0f68dc01-2071-43ac-8f8c-f14fd07d362d",
   "metadata": {
    "collapsed": true,
    "jupyter": {
     "outputs_hidden": true
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "((np.int32(1), '女'),      Python\n",
      "6        38\n",
      "35       99\n",
      "46       74\n",
      "48       70\n",
      "55      107\n",
      "62       88\n",
      "71      140\n",
      "73       91\n",
      "75       89\n",
      "77      113\n",
      "99       83\n",
      "110      96\n",
      "120     106\n",
      "129      61\n",
      "132     108\n",
      "137      80\n",
      "145      53\n",
      "174     148\n",
      "190     101\n",
      "232     116\n",
      "240      58\n",
      "272      57\n",
      "277      57)\n",
      "((np.int32(1), '男'),      Python\n",
      "18      139\n",
      "61      109\n",
      "89      136\n",
      "111      66\n",
      "118       2\n",
      "143     107\n",
      "150     140\n",
      "163       8\n",
      "181      65\n",
      "195      22\n",
      "202     106\n",
      "210      86\n",
      "220      65\n",
      "224     144\n",
      "225     129\n",
      "242      80\n",
      "267      61\n",
      "280      69\n",
      "283      22\n",
      "285     135\n",
      "291     145\n",
      "297      34)\n",
      "((np.int32(2), '女'),      Python\n",
      "58       28\n",
      "72      137\n",
      "81      145\n",
      "95       41\n",
      "113     118\n",
      "117      16\n",
      "142      94\n",
      "153      24\n",
      "189      77\n",
      "201      92\n",
      "203       9\n",
      "222      31\n",
      "227      92\n",
      "258      84\n",
      "284      46\n",
      "299      23)\n",
      "((np.int32(2), '男'),      Python\n",
      "19       30\n",
      "43      145\n",
      "44      146\n",
      "92       99\n",
      "106     101\n",
      "193      76\n",
      "205       6\n",
      "230      90\n",
      "234     118\n",
      "237     147\n",
      "239     130\n",
      "255       1\n",
      "270     118\n",
      "271      66\n",
      "290     114\n",
      "295      67)\n",
      "((np.int32(3), '女'),      Python\n",
      "8        49\n",
      "41      135\n",
      "45        1\n",
      "56       30\n",
      "57      144\n",
      "87       65\n",
      "116       2\n",
      "136      84\n",
      "151     137\n",
      "158     123\n",
      "159     132\n",
      "173      75\n",
      "178     130\n",
      "187     128\n",
      "191      30\n",
      "197     110\n",
      "200      42\n",
      "217      52\n",
      "248      49\n",
      "281     126\n",
      "287     126)\n",
      "((np.int32(3), '男'),      Python\n",
      "1        87\n",
      "2         9\n",
      "28       80\n",
      "32       49\n",
      "53       63\n",
      "63      146\n",
      "105     135\n",
      "156     145\n",
      "177      77\n",
      "185      29\n",
      "198      38\n",
      "218      54\n",
      "276      28)\n",
      "((np.int32(4), '女'),      Python\n",
      "9       148\n",
      "23      132\n",
      "86       88\n",
      "98      143\n",
      "108      70\n",
      "166       4\n",
      "171      53\n",
      "184     120\n",
      "209      85\n",
      "219      82\n",
      "233     125\n",
      "245      35\n",
      "249      19\n",
      "286      53)\n",
      "((np.int32(4), '男'),      Python\n",
      "3       115\n",
      "15      115\n",
      "33       39\n",
      "51       76\n",
      "64       56\n",
      "65       17\n",
      "68       71\n",
      "91       55\n",
      "109     148\n",
      "114      79\n",
      "122     106\n",
      "130      93\n",
      "131      28\n",
      "135      25\n",
      "157      59\n",
      "167      19\n",
      "186      47\n",
      "196      50\n",
      "199      13\n",
      "254      32\n",
      "263      30\n",
      "268     114\n",
      "293      92\n",
      "298      11)\n",
      "((np.int32(5), '女'),      Python\n",
      "10       51\n",
      "59       10\n",
      "76      131\n",
      "82      125\n",
      "85       58\n",
      "88       52\n",
      "104     137\n",
      "112     123\n",
      "126      56\n",
      "179     126\n",
      "194      60\n",
      "204     135\n",
      "207       2\n",
      "213      42\n",
      "229     144\n",
      "266      63\n",
      "288     120)\n",
      "((np.int32(5), '男'),      Python\n",
      "4       116\n",
      "47      119\n",
      "50       64\n",
      "100      55\n",
      "125      19\n",
      "133      89\n",
      "134       3\n",
      "221      67\n",
      "244      90\n",
      "257     112\n",
      "279     123\n",
      "294     144)\n",
      "((np.int32(6), '女'),      Python\n",
      "12       30\n",
      "24       74\n",
      "26      150\n",
      "29      101\n",
      "31       46\n",
      "66       62\n",
      "83        4\n",
      "90       97\n",
      "94       38\n",
      "96      104\n",
      "107      66\n",
      "115      15\n",
      "121     132\n",
      "123     118\n",
      "147     101\n",
      "161      35\n",
      "168       4\n",
      "206       6\n",
      "212      90\n",
      "226      59\n",
      "228      19\n",
      "259      89\n",
      "274      40)\n",
      "((np.int32(6), '男'),      Python\n",
      "17      101\n",
      "21      112\n",
      "22      117\n",
      "34       21\n",
      "39       12\n",
      "40      108\n",
      "42        3\n",
      "124     125\n",
      "128      74\n",
      "140      99\n",
      "149       4\n",
      "162      61\n",
      "170      43\n",
      "172      99\n",
      "216     142\n",
      "223     107\n",
      "250      33\n",
      "256     110\n",
      "261      93\n",
      "264      37\n",
      "265      26\n",
      "289      57\n",
      "292      85)\n",
      "((np.int32(7), '女'),      Python\n",
      "5       101\n",
      "14       77\n",
      "16      124\n",
      "69       87\n",
      "79       14\n",
      "80      126\n",
      "119      94\n",
      "127     123\n",
      "144      38\n",
      "146      31\n",
      "164     119\n",
      "169     101\n",
      "183      36\n",
      "214       2\n",
      "231       4\n",
      "236      64\n",
      "246     118\n",
      "247      30\n",
      "260      49\n",
      "269      31\n",
      "273      97\n",
      "282     139)\n",
      "((np.int32(7), '男'),      Python\n",
      "7        13\n",
      "37       18\n",
      "38      126\n",
      "52      150\n",
      "54       31\n",
      "101      53\n",
      "102      28\n",
      "139      43\n",
      "141     145\n",
      "154      39\n",
      "160     137\n",
      "188     125\n",
      "192      75\n",
      "215      90\n",
      "241      84\n",
      "253      98\n",
      "278      43)\n",
      "((np.int32(8), '女'),      Python\n",
      "20       17\n",
      "25       43\n",
      "27      147\n",
      "49       63\n",
      "67      147\n",
      "70      141\n",
      "74      118\n",
      "84      120\n",
      "93       39\n",
      "97       50\n",
      "103      99\n",
      "138       3\n",
      "175      61\n",
      "176      89\n",
      "180      76\n",
      "208      51\n",
      "211      38\n",
      "235     118\n",
      "243      96\n",
      "251     123\n",
      "252      25\n",
      "296     129)\n",
      "((np.int32(8), '男'),      Python\n",
      "0       126\n",
      "11       97\n",
      "13       52\n",
      "30        4\n",
      "36      119\n",
      "60      124\n",
      "78      141\n",
      "148      62\n",
      "152      32\n",
      "155     102\n",
      "165      24\n",
      "182     101\n",
      "238      93\n",
      "262     136\n",
      "275      40)\n"
     ]
    }
   ],
   "source": [
    "for item in g:\n",
    "    print(item)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "95c6461f-5f61-4e48-b4c4-29dc65f39ecc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<pandas.core.groupby.generic.SeriesGroupBy object at 0x00000200154414B0>"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 对一列值进行分组\n",
    "df['Python'].groupby(df['class'])  # 单分组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "6321b751-dd40-48da-b373-75c7b5eab047",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<pandas.core.groupby.generic.SeriesGroupBy object at 0x0000020016FEC7C0>"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df['Keras'].groupby([df['class'], df['sex']])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "42aeba35-bb5f-4b29-a047-52ffc565e4d7",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\ADMIN\\AppData\\Local\\Temp\\ipykernel_6140\\1620964791.py:2: FutureWarning: DataFrame.groupby with axis=1 is deprecated. Do `frame.T.groupby(...)` without axis instead.\n",
      "  df.groupby(df.dtypes, axis=1)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<pandas.core.groupby.generic.DataFrameGroupBy object at 0x00000200163AFC70>"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 按照数据类型分组\n",
    "df.groupby(df.dtypes, axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "48b11529-37a8-4a4b-a226-6863fc0a0429",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "组名 IT\n",
      "数据      Python  Keras  Tensorflow  Java  C++\n",
      "0       126    149         137   129  126\n",
      "1        87    138          76   140  124\n",
      "2         9     33         136   138   12\n",
      "3       115    108          63     5   85\n",
      "4       116     20         108     0  120\n",
      "..      ...    ...         ...   ...  ...\n",
      "295      67     60          62    51  129\n",
      "296     129    139          47   124  143\n",
      "297      34     27         126   124   17\n",
      "298      11     94         126    69  131\n",
      "299      23     22         146   128   46\n",
      "\n",
      "[300 rows x 5 columns]\n",
      "组名 category\n",
      "数据     sex  class\n",
      "0     男      8\n",
      "1     男      3\n",
      "2     男      3\n",
      "3     男      4\n",
      "4     男      5\n",
      "..   ..    ...\n",
      "295   男      2\n",
      "296   女      8\n",
      "297   男      1\n",
      "298   男      4\n",
      "299   女      2\n",
      "\n",
      "[300 rows x 2 columns]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\ADMIN\\AppData\\Local\\Temp\\ipykernel_6140\\580833725.py:12: FutureWarning: DataFrame.groupby with axis=1 is deprecated. Do `frame.T.groupby(...)` without axis instead.\n",
      "  for name, data in df.groupby(my_map, axis=1):\n"
     ]
    }
   ],
   "source": [
    "# 通过字典来分组\n",
    "my_map = {\n",
    "    'sex':'category',\n",
    "    'class':'category',\n",
    "    'Python':'IT',\n",
    "    'Keras':'IT',\n",
    "    'Tensorflow':'IT',\n",
    "    'Java':'IT',\n",
    "    'C++':'IT'\n",
    "}\n",
    "\n",
    "for name, data in df.groupby(my_map, axis=1):\n",
    "    print('组名',name)\n",
    "    print('数据',data)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a8411aaa-e5ef-4493-affe-93becf13104f",
   "metadata": {},
   "source": [
    "## （2）分组聚合"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "ad33cd9b-1b95-40f9-975a-67e634115ce8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>class</th>\n",
       "      <th>Python</th>\n",
       "      <th>Keras</th>\n",
       "      <th>Tensorflow</th>\n",
       "      <th>Java</th>\n",
       "      <th>C++</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>sex</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>女</th>\n",
       "      <td>4.6</td>\n",
       "      <td>78.0</td>\n",
       "      <td>74.5</td>\n",
       "      <td>76.6</td>\n",
       "      <td>76.0</td>\n",
       "      <td>73.6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>4.4</td>\n",
       "      <td>77.3</td>\n",
       "      <td>79.6</td>\n",
       "      <td>78.6</td>\n",
       "      <td>75.6</td>\n",
       "      <td>75.9</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     class  Python  Keras  Tensorflow  Java   C++\n",
       "sex                                              \n",
       "女      4.6    78.0   74.5        76.6  76.0  73.6\n",
       "男      4.4    77.3   79.6        78.6  75.6  75.9"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 分组直接调用函数进行聚合\n",
    "# 按照性别分组，然后其他列均值聚合\n",
    "df.groupby(by='sex').mean().round(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "073db62e-5840-42b5-a511-b553778a67cf",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>Python</th>\n",
       "      <th>Keras</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>class</th>\n",
       "      <th>sex</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">1</th>\n",
       "      <th>女</th>\n",
       "      <td>148</td>\n",
       "      <td>150</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>145</td>\n",
       "      <td>145</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">2</th>\n",
       "      <th>女</th>\n",
       "      <td>145</td>\n",
       "      <td>143</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>147</td>\n",
       "      <td>147</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">3</th>\n",
       "      <th>女</th>\n",
       "      <td>144</td>\n",
       "      <td>146</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>146</td>\n",
       "      <td>138</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">4</th>\n",
       "      <th>女</th>\n",
       "      <td>148</td>\n",
       "      <td>143</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>148</td>\n",
       "      <td>139</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">5</th>\n",
       "      <th>女</th>\n",
       "      <td>144</td>\n",
       "      <td>148</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>144</td>\n",
       "      <td>139</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">6</th>\n",
       "      <th>女</th>\n",
       "      <td>150</td>\n",
       "      <td>143</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>142</td>\n",
       "      <td>140</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">7</th>\n",
       "      <th>女</th>\n",
       "      <td>139</td>\n",
       "      <td>140</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>150</td>\n",
       "      <td>144</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">8</th>\n",
       "      <th>女</th>\n",
       "      <td>147</td>\n",
       "      <td>140</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>141</td>\n",
       "      <td>149</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           Python  Keras\n",
       "class sex               \n",
       "1     女       148    150\n",
       "      男       145    145\n",
       "2     女       145    143\n",
       "      男       147    147\n",
       "3     女       144    146\n",
       "      男       146    138\n",
       "4     女       148    143\n",
       "      男       148    139\n",
       "5     女       144    148\n",
       "      男       144    139\n",
       "6     女       150    143\n",
       "      男       142    140\n",
       "7     女       139    140\n",
       "      男       150    144\n",
       "8     女       147    140\n",
       "      男       141    149"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 按照班级和性别进行分组，Python，Keras的最大值聚合\n",
    "df.groupby(by=['class', 'sex'])[['Python', 'Keras']].max()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "a16bcff7-4fca-4e32-8930-aa7b698dee7f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "class  sex\n",
       "1      女      23\n",
       "       男      22\n",
       "2      女      16\n",
       "       男      16\n",
       "3      女      21\n",
       "       男      13\n",
       "4      女      14\n",
       "       男      24\n",
       "5      女      17\n",
       "       男      12\n",
       "6      女      23\n",
       "       男      23\n",
       "7      女      22\n",
       "       男      17\n",
       "8      女      22\n",
       "       男      15\n",
       "dtype: int64"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 按照班级和性别进行分组，计算聚合统计每个班男女人数\n",
    "df.groupby(by=['class', 'sex']).size()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "ff6e7773-d3bb-47a5-ade7-aa7c223623ee",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr:last-of-type th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th colspan=\"8\" halign=\"left\">Python</th>\n",
       "      <th colspan=\"2\" halign=\"left\">Keras</th>\n",
       "      <th>...</th>\n",
       "      <th colspan=\"2\" halign=\"left\">Java</th>\n",
       "      <th colspan=\"8\" halign=\"left\">C++</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>count</th>\n",
       "      <th>mean</th>\n",
       "      <th>std</th>\n",
       "      <th>min</th>\n",
       "      <th>25%</th>\n",
       "      <th>50%</th>\n",
       "      <th>75%</th>\n",
       "      <th>max</th>\n",
       "      <th>count</th>\n",
       "      <th>mean</th>\n",
       "      <th>...</th>\n",
       "      <th>75%</th>\n",
       "      <th>max</th>\n",
       "      <th>count</th>\n",
       "      <th>mean</th>\n",
       "      <th>std</th>\n",
       "      <th>min</th>\n",
       "      <th>25%</th>\n",
       "      <th>50%</th>\n",
       "      <th>75%</th>\n",
       "      <th>max</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>class</th>\n",
       "      <th>sex</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">1</th>\n",
       "      <th>女</th>\n",
       "      <td>23.0</td>\n",
       "      <td>88.391304</td>\n",
       "      <td>27.833497</td>\n",
       "      <td>38.0</td>\n",
       "      <td>65.50</td>\n",
       "      <td>89.0</td>\n",
       "      <td>106.50</td>\n",
       "      <td>148.0</td>\n",
       "      <td>23.0</td>\n",
       "      <td>75.739130</td>\n",
       "      <td>...</td>\n",
       "      <td>95.00</td>\n",
       "      <td>145.0</td>\n",
       "      <td>23.0</td>\n",
       "      <td>81.000000</td>\n",
       "      <td>42.160947</td>\n",
       "      <td>1.0</td>\n",
       "      <td>48.50</td>\n",
       "      <td>75.0</td>\n",
       "      <td>116.00</td>\n",
       "      <td>144.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>22.0</td>\n",
       "      <td>85.000000</td>\n",
       "      <td>47.276290</td>\n",
       "      <td>2.0</td>\n",
       "      <td>62.00</td>\n",
       "      <td>83.0</td>\n",
       "      <td>133.50</td>\n",
       "      <td>145.0</td>\n",
       "      <td>22.0</td>\n",
       "      <td>72.136364</td>\n",
       "      <td>...</td>\n",
       "      <td>122.00</td>\n",
       "      <td>147.0</td>\n",
       "      <td>22.0</td>\n",
       "      <td>51.681818</td>\n",
       "      <td>33.685360</td>\n",
       "      <td>8.0</td>\n",
       "      <td>27.75</td>\n",
       "      <td>43.5</td>\n",
       "      <td>73.00</td>\n",
       "      <td>123.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">2</th>\n",
       "      <th>女</th>\n",
       "      <td>16.0</td>\n",
       "      <td>66.062500</td>\n",
       "      <td>44.439425</td>\n",
       "      <td>9.0</td>\n",
       "      <td>27.00</td>\n",
       "      <td>61.5</td>\n",
       "      <td>92.50</td>\n",
       "      <td>145.0</td>\n",
       "      <td>16.0</td>\n",
       "      <td>65.937500</td>\n",
       "      <td>...</td>\n",
       "      <td>129.25</td>\n",
       "      <td>150.0</td>\n",
       "      <td>16.0</td>\n",
       "      <td>54.687500</td>\n",
       "      <td>38.409580</td>\n",
       "      <td>16.0</td>\n",
       "      <td>31.25</td>\n",
       "      <td>38.5</td>\n",
       "      <td>70.75</td>\n",
       "      <td>148.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>16.0</td>\n",
       "      <td>90.875000</td>\n",
       "      <td>47.061485</td>\n",
       "      <td>1.0</td>\n",
       "      <td>66.75</td>\n",
       "      <td>100.0</td>\n",
       "      <td>121.00</td>\n",
       "      <td>147.0</td>\n",
       "      <td>16.0</td>\n",
       "      <td>75.562500</td>\n",
       "      <td>...</td>\n",
       "      <td>102.50</td>\n",
       "      <td>147.0</td>\n",
       "      <td>16.0</td>\n",
       "      <td>71.125000</td>\n",
       "      <td>49.537696</td>\n",
       "      <td>6.0</td>\n",
       "      <td>19.25</td>\n",
       "      <td>77.5</td>\n",
       "      <td>111.00</td>\n",
       "      <td>146.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">3</th>\n",
       "      <th>女</th>\n",
       "      <td>21.0</td>\n",
       "      <td>84.285714</td>\n",
       "      <td>48.069890</td>\n",
       "      <td>1.0</td>\n",
       "      <td>49.00</td>\n",
       "      <td>84.0</td>\n",
       "      <td>128.00</td>\n",
       "      <td>144.0</td>\n",
       "      <td>21.0</td>\n",
       "      <td>78.666667</td>\n",
       "      <td>...</td>\n",
       "      <td>128.00</td>\n",
       "      <td>149.0</td>\n",
       "      <td>21.0</td>\n",
       "      <td>85.428571</td>\n",
       "      <td>45.022851</td>\n",
       "      <td>2.0</td>\n",
       "      <td>61.00</td>\n",
       "      <td>89.0</td>\n",
       "      <td>120.00</td>\n",
       "      <td>147.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>13.0</td>\n",
       "      <td>72.307692</td>\n",
       "      <td>45.580304</td>\n",
       "      <td>9.0</td>\n",
       "      <td>38.00</td>\n",
       "      <td>63.0</td>\n",
       "      <td>87.00</td>\n",
       "      <td>146.0</td>\n",
       "      <td>13.0</td>\n",
       "      <td>81.692308</td>\n",
       "      <td>...</td>\n",
       "      <td>107.00</td>\n",
       "      <td>140.0</td>\n",
       "      <td>13.0</td>\n",
       "      <td>84.923077</td>\n",
       "      <td>42.254115</td>\n",
       "      <td>12.0</td>\n",
       "      <td>62.00</td>\n",
       "      <td>87.0</td>\n",
       "      <td>124.00</td>\n",
       "      <td>142.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">4</th>\n",
       "      <th>女</th>\n",
       "      <td>14.0</td>\n",
       "      <td>82.642857</td>\n",
       "      <td>46.407239</td>\n",
       "      <td>4.0</td>\n",
       "      <td>53.00</td>\n",
       "      <td>83.5</td>\n",
       "      <td>123.75</td>\n",
       "      <td>148.0</td>\n",
       "      <td>14.0</td>\n",
       "      <td>89.571429</td>\n",
       "      <td>...</td>\n",
       "      <td>89.75</td>\n",
       "      <td>136.0</td>\n",
       "      <td>14.0</td>\n",
       "      <td>68.428571</td>\n",
       "      <td>52.979988</td>\n",
       "      <td>2.0</td>\n",
       "      <td>17.75</td>\n",
       "      <td>60.5</td>\n",
       "      <td>111.25</td>\n",
       "      <td>147.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>24.0</td>\n",
       "      <td>62.083333</td>\n",
       "      <td>38.672445</td>\n",
       "      <td>11.0</td>\n",
       "      <td>29.50</td>\n",
       "      <td>55.5</td>\n",
       "      <td>92.25</td>\n",
       "      <td>148.0</td>\n",
       "      <td>24.0</td>\n",
       "      <td>70.916667</td>\n",
       "      <td>...</td>\n",
       "      <td>81.00</td>\n",
       "      <td>144.0</td>\n",
       "      <td>24.0</td>\n",
       "      <td>90.166667</td>\n",
       "      <td>42.895897</td>\n",
       "      <td>14.0</td>\n",
       "      <td>64.00</td>\n",
       "      <td>96.5</td>\n",
       "      <td>122.75</td>\n",
       "      <td>149.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">5</th>\n",
       "      <th>女</th>\n",
       "      <td>17.0</td>\n",
       "      <td>84.411765</td>\n",
       "      <td>47.455320</td>\n",
       "      <td>2.0</td>\n",
       "      <td>52.00</td>\n",
       "      <td>63.0</td>\n",
       "      <td>126.00</td>\n",
       "      <td>144.0</td>\n",
       "      <td>17.0</td>\n",
       "      <td>80.000000</td>\n",
       "      <td>...</td>\n",
       "      <td>115.00</td>\n",
       "      <td>133.0</td>\n",
       "      <td>17.0</td>\n",
       "      <td>70.823529</td>\n",
       "      <td>49.357415</td>\n",
       "      <td>1.0</td>\n",
       "      <td>29.00</td>\n",
       "      <td>74.0</td>\n",
       "      <td>111.00</td>\n",
       "      <td>144.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>12.0</td>\n",
       "      <td>83.416667</td>\n",
       "      <td>43.198187</td>\n",
       "      <td>3.0</td>\n",
       "      <td>61.75</td>\n",
       "      <td>89.5</td>\n",
       "      <td>116.75</td>\n",
       "      <td>144.0</td>\n",
       "      <td>12.0</td>\n",
       "      <td>87.000000</td>\n",
       "      <td>...</td>\n",
       "      <td>134.00</td>\n",
       "      <td>146.0</td>\n",
       "      <td>12.0</td>\n",
       "      <td>81.916667</td>\n",
       "      <td>50.946422</td>\n",
       "      <td>19.0</td>\n",
       "      <td>29.00</td>\n",
       "      <td>95.0</td>\n",
       "      <td>124.00</td>\n",
       "      <td>145.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">6</th>\n",
       "      <th>女</th>\n",
       "      <td>23.0</td>\n",
       "      <td>64.347826</td>\n",
       "      <td>42.830118</td>\n",
       "      <td>4.0</td>\n",
       "      <td>32.50</td>\n",
       "      <td>62.0</td>\n",
       "      <td>99.00</td>\n",
       "      <td>150.0</td>\n",
       "      <td>23.0</td>\n",
       "      <td>79.130435</td>\n",
       "      <td>...</td>\n",
       "      <td>114.00</td>\n",
       "      <td>137.0</td>\n",
       "      <td>23.0</td>\n",
       "      <td>62.695652</td>\n",
       "      <td>39.870740</td>\n",
       "      <td>1.0</td>\n",
       "      <td>39.00</td>\n",
       "      <td>58.0</td>\n",
       "      <td>82.50</td>\n",
       "      <td>150.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>23.0</td>\n",
       "      <td>72.565217</td>\n",
       "      <td>42.554592</td>\n",
       "      <td>3.0</td>\n",
       "      <td>35.00</td>\n",
       "      <td>85.0</td>\n",
       "      <td>107.50</td>\n",
       "      <td>142.0</td>\n",
       "      <td>23.0</td>\n",
       "      <td>76.869565</td>\n",
       "      <td>...</td>\n",
       "      <td>104.50</td>\n",
       "      <td>147.0</td>\n",
       "      <td>23.0</td>\n",
       "      <td>79.173913</td>\n",
       "      <td>44.657945</td>\n",
       "      <td>4.0</td>\n",
       "      <td>46.50</td>\n",
       "      <td>96.0</td>\n",
       "      <td>114.00</td>\n",
       "      <td>150.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">7</th>\n",
       "      <th>女</th>\n",
       "      <td>22.0</td>\n",
       "      <td>72.954545</td>\n",
       "      <td>44.247655</td>\n",
       "      <td>2.0</td>\n",
       "      <td>32.25</td>\n",
       "      <td>82.0</td>\n",
       "      <td>113.75</td>\n",
       "      <td>139.0</td>\n",
       "      <td>22.0</td>\n",
       "      <td>54.772727</td>\n",
       "      <td>...</td>\n",
       "      <td>119.00</td>\n",
       "      <td>149.0</td>\n",
       "      <td>22.0</td>\n",
       "      <td>70.363636</td>\n",
       "      <td>30.311942</td>\n",
       "      <td>20.0</td>\n",
       "      <td>48.25</td>\n",
       "      <td>61.0</td>\n",
       "      <td>96.25</td>\n",
       "      <td>128.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>17.0</td>\n",
       "      <td>76.352941</td>\n",
       "      <td>46.997262</td>\n",
       "      <td>13.0</td>\n",
       "      <td>39.00</td>\n",
       "      <td>75.0</td>\n",
       "      <td>125.00</td>\n",
       "      <td>150.0</td>\n",
       "      <td>17.0</td>\n",
       "      <td>82.235294</td>\n",
       "      <td>...</td>\n",
       "      <td>104.00</td>\n",
       "      <td>150.0</td>\n",
       "      <td>17.0</td>\n",
       "      <td>83.705882</td>\n",
       "      <td>32.630057</td>\n",
       "      <td>20.0</td>\n",
       "      <td>65.00</td>\n",
       "      <td>89.0</td>\n",
       "      <td>105.00</td>\n",
       "      <td>130.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">8</th>\n",
       "      <th>女</th>\n",
       "      <td>22.0</td>\n",
       "      <td>81.500000</td>\n",
       "      <td>44.843378</td>\n",
       "      <td>3.0</td>\n",
       "      <td>44.75</td>\n",
       "      <td>82.5</td>\n",
       "      <td>119.50</td>\n",
       "      <td>147.0</td>\n",
       "      <td>22.0</td>\n",
       "      <td>76.363636</td>\n",
       "      <td>...</td>\n",
       "      <td>109.25</td>\n",
       "      <td>137.0</td>\n",
       "      <td>22.0</td>\n",
       "      <td>88.181818</td>\n",
       "      <td>37.789689</td>\n",
       "      <td>23.0</td>\n",
       "      <td>62.25</td>\n",
       "      <td>89.0</td>\n",
       "      <td>115.25</td>\n",
       "      <td>143.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>15.0</td>\n",
       "      <td>83.533333</td>\n",
       "      <td>44.360321</td>\n",
       "      <td>4.0</td>\n",
       "      <td>46.00</td>\n",
       "      <td>97.0</td>\n",
       "      <td>121.50</td>\n",
       "      <td>141.0</td>\n",
       "      <td>15.0</td>\n",
       "      <td>102.000000</td>\n",
       "      <td>...</td>\n",
       "      <td>130.50</td>\n",
       "      <td>142.0</td>\n",
       "      <td>15.0</td>\n",
       "      <td>67.600000</td>\n",
       "      <td>44.345720</td>\n",
       "      <td>2.0</td>\n",
       "      <td>34.50</td>\n",
       "      <td>66.0</td>\n",
       "      <td>90.00</td>\n",
       "      <td>142.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>16 rows × 40 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "          Python                                                           \\\n",
       "           count       mean        std   min    25%    50%     75%    max   \n",
       "class sex                                                                   \n",
       "1     女     23.0  88.391304  27.833497  38.0  65.50   89.0  106.50  148.0   \n",
       "      男     22.0  85.000000  47.276290   2.0  62.00   83.0  133.50  145.0   \n",
       "2     女     16.0  66.062500  44.439425   9.0  27.00   61.5   92.50  145.0   \n",
       "      男     16.0  90.875000  47.061485   1.0  66.75  100.0  121.00  147.0   \n",
       "3     女     21.0  84.285714  48.069890   1.0  49.00   84.0  128.00  144.0   \n",
       "      男     13.0  72.307692  45.580304   9.0  38.00   63.0   87.00  146.0   \n",
       "4     女     14.0  82.642857  46.407239   4.0  53.00   83.5  123.75  148.0   \n",
       "      男     24.0  62.083333  38.672445  11.0  29.50   55.5   92.25  148.0   \n",
       "5     女     17.0  84.411765  47.455320   2.0  52.00   63.0  126.00  144.0   \n",
       "      男     12.0  83.416667  43.198187   3.0  61.75   89.5  116.75  144.0   \n",
       "6     女     23.0  64.347826  42.830118   4.0  32.50   62.0   99.00  150.0   \n",
       "      男     23.0  72.565217  42.554592   3.0  35.00   85.0  107.50  142.0   \n",
       "7     女     22.0  72.954545  44.247655   2.0  32.25   82.0  113.75  139.0   \n",
       "      男     17.0  76.352941  46.997262  13.0  39.00   75.0  125.00  150.0   \n",
       "8     女     22.0  81.500000  44.843378   3.0  44.75   82.5  119.50  147.0   \n",
       "      男     15.0  83.533333  44.360321   4.0  46.00   97.0  121.50  141.0   \n",
       "\n",
       "          Keras              ...    Java          C++                        \\\n",
       "          count        mean  ...     75%    max count       mean        std   \n",
       "class sex                    ...                                              \n",
       "1     女    23.0   75.739130  ...   95.00  145.0  23.0  81.000000  42.160947   \n",
       "      男    22.0   72.136364  ...  122.00  147.0  22.0  51.681818  33.685360   \n",
       "2     女    16.0   65.937500  ...  129.25  150.0  16.0  54.687500  38.409580   \n",
       "      男    16.0   75.562500  ...  102.50  147.0  16.0  71.125000  49.537696   \n",
       "3     女    21.0   78.666667  ...  128.00  149.0  21.0  85.428571  45.022851   \n",
       "      男    13.0   81.692308  ...  107.00  140.0  13.0  84.923077  42.254115   \n",
       "4     女    14.0   89.571429  ...   89.75  136.0  14.0  68.428571  52.979988   \n",
       "      男    24.0   70.916667  ...   81.00  144.0  24.0  90.166667  42.895897   \n",
       "5     女    17.0   80.000000  ...  115.00  133.0  17.0  70.823529  49.357415   \n",
       "      男    12.0   87.000000  ...  134.00  146.0  12.0  81.916667  50.946422   \n",
       "6     女    23.0   79.130435  ...  114.00  137.0  23.0  62.695652  39.870740   \n",
       "      男    23.0   76.869565  ...  104.50  147.0  23.0  79.173913  44.657945   \n",
       "7     女    22.0   54.772727  ...  119.00  149.0  22.0  70.363636  30.311942   \n",
       "      男    17.0   82.235294  ...  104.00  150.0  17.0  83.705882  32.630057   \n",
       "8     女    22.0   76.363636  ...  109.25  137.0  22.0  88.181818  37.789689   \n",
       "      男    15.0  102.000000  ...  130.50  142.0  15.0  67.600000  44.345720   \n",
       "\n",
       "                                             \n",
       "            min    25%   50%     75%    max  \n",
       "class sex                                    \n",
       "1     女     1.0  48.50  75.0  116.00  144.0  \n",
       "      男     8.0  27.75  43.5   73.00  123.0  \n",
       "2     女    16.0  31.25  38.5   70.75  148.0  \n",
       "      男     6.0  19.25  77.5  111.00  146.0  \n",
       "3     女     2.0  61.00  89.0  120.00  147.0  \n",
       "      男    12.0  62.00  87.0  124.00  142.0  \n",
       "4     女     2.0  17.75  60.5  111.25  147.0  \n",
       "      男    14.0  64.00  96.5  122.75  149.0  \n",
       "5     女     1.0  29.00  74.0  111.00  144.0  \n",
       "      男    19.0  29.00  95.0  124.00  145.0  \n",
       "6     女     1.0  39.00  58.0   82.50  150.0  \n",
       "      男     4.0  46.50  96.0  114.00  150.0  \n",
       "7     女    20.0  48.25  61.0   96.25  128.0  \n",
       "      男    20.0  65.00  89.0  105.00  130.0  \n",
       "8     女    23.0  62.25  89.0  115.25  143.0  \n",
       "      男     2.0  34.50  66.0   90.00  142.0  \n",
       "\n",
       "[16 rows x 40 columns]"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 基本描述性统计聚合\n",
    "df.groupby(by=['class', 'sex']).describe()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eecfa731-e2fb-4ff1-8f70-bcf359d89d9e",
   "metadata": {},
   "source": [
    "## （3）分组聚合后使用apply和transform"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "e823648e-57c1-4c83-9f56-1a01f2637b86",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "class  sex\n",
       "1      女      82.065217\n",
       "       男      78.568182\n",
       "2      女      66.000000\n",
       "       男      83.218750\n",
       "3      女      81.476190\n",
       "       男      77.000000\n",
       "4      女      86.107143\n",
       "       男      66.500000\n",
       "5      女      82.205882\n",
       "       男      85.208333\n",
       "6      女      71.739130\n",
       "       男      74.717391\n",
       "7      女      63.863636\n",
       "       男      79.294118\n",
       "8      女      78.931818\n",
       "       男      92.766667\n",
       "dtype: float64"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 分组调用apply、transform封装单一函数计算\n",
    "df.groupby(by=['class', 'sex'])[['Python', 'Keras']].apply(np.mean)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "8d0e3ffd-97fd-4e12-8364-5d85d608177d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Python</th>\n",
       "      <th>Tensorflow</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.891</td>\n",
       "      <td>0.952</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.569</td>\n",
       "      <td>0.489</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.000</td>\n",
       "      <td>0.915</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.759</td>\n",
       "      <td>0.414</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.801</td>\n",
       "      <td>0.776</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>295</th>\n",
       "      <td>0.452</td>\n",
       "      <td>0.492</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>296</th>\n",
       "      <td>0.875</td>\n",
       "      <td>0.238</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>297</th>\n",
       "      <td>0.224</td>\n",
       "      <td>0.820</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>298</th>\n",
       "      <td>0.000</td>\n",
       "      <td>0.848</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>299</th>\n",
       "      <td>0.103</td>\n",
       "      <td>1.000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>300 rows × 2 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "     Python  Tensorflow\n",
       "0     0.891       0.952\n",
       "1     0.569       0.489\n",
       "2     0.000       0.915\n",
       "3     0.759       0.414\n",
       "4     0.801       0.776\n",
       "..      ...         ...\n",
       "295   0.452       0.492\n",
       "296   0.875       0.238\n",
       "297   0.224       0.820\n",
       "298   0.000       0.848\n",
       "299   0.103       1.000\n",
       "\n",
       "[300 rows x 2 columns]"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 定义一个函数，分组聚合后调用这个函数来处理数据\n",
    "def normalization(x):\n",
    "    return (x - x.min()) / (x.max() - x.min())\n",
    "\n",
    "df.groupby(by=['class', 'sex'])[['Python', 'Tensorflow']].transform(normalization).round(3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3c3f8bc9-fd47-4cb3-a2e9-176e49139f49",
   "metadata": {},
   "source": [
    "## （4）分组聚合后使用agg"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "0e3eb4b0-ab13-416f-9df1-db0d1b6ad264",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr:last-of-type th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th colspan=\"2\" halign=\"left\">Tensorflow</th>\n",
       "      <th colspan=\"2\" halign=\"left\">Keras</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>max</th>\n",
       "      <th>min</th>\n",
       "      <th>max</th>\n",
       "      <th>min</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>class</th>\n",
       "      <th>sex</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">1</th>\n",
       "      <th>女</th>\n",
       "      <td>148</td>\n",
       "      <td>1</td>\n",
       "      <td>150</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>149</td>\n",
       "      <td>21</td>\n",
       "      <td>145</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">2</th>\n",
       "      <th>女</th>\n",
       "      <td>146</td>\n",
       "      <td>6</td>\n",
       "      <td>143</td>\n",
       "      <td>11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>122</td>\n",
       "      <td>4</td>\n",
       "      <td>147</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">3</th>\n",
       "      <th>女</th>\n",
       "      <td>123</td>\n",
       "      <td>34</td>\n",
       "      <td>146</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>148</td>\n",
       "      <td>7</td>\n",
       "      <td>138</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">4</th>\n",
       "      <th>女</th>\n",
       "      <td>133</td>\n",
       "      <td>1</td>\n",
       "      <td>143</td>\n",
       "      <td>11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>148</td>\n",
       "      <td>3</td>\n",
       "      <td>139</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">5</th>\n",
       "      <th>女</th>\n",
       "      <td>139</td>\n",
       "      <td>4</td>\n",
       "      <td>148</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>138</td>\n",
       "      <td>4</td>\n",
       "      <td>139</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">6</th>\n",
       "      <th>女</th>\n",
       "      <td>150</td>\n",
       "      <td>0</td>\n",
       "      <td>143</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>150</td>\n",
       "      <td>2</td>\n",
       "      <td>140</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">7</th>\n",
       "      <th>女</th>\n",
       "      <td>149</td>\n",
       "      <td>18</td>\n",
       "      <td>140</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>147</td>\n",
       "      <td>13</td>\n",
       "      <td>144</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">8</th>\n",
       "      <th>女</th>\n",
       "      <td>146</td>\n",
       "      <td>16</td>\n",
       "      <td>140</td>\n",
       "      <td>12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>143</td>\n",
       "      <td>19</td>\n",
       "      <td>149</td>\n",
       "      <td>18</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          Tensorflow     Keras    \n",
       "                 max min   max min\n",
       "class sex                         \n",
       "1     女          148   1   150   1\n",
       "      男          149  21   145   3\n",
       "2     女          146   6   143  11\n",
       "      男          122   4   147   5\n",
       "3     女          123  34   146   5\n",
       "      男          148   7   138   1\n",
       "4     女          133   1   143  11\n",
       "      男          148   3   139   2\n",
       "5     女          139   4   148   4\n",
       "      男          138   4   139   4\n",
       "6     女          150   0   143   4\n",
       "      男          150   2   140   7\n",
       "7     女          149  18   140   1\n",
       "      男          147  13   144   7\n",
       "8     女          146  16   140  12\n",
       "      男          143  19   149  18"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 分组后调用agg应用多种统计汇总\n",
    "df.groupby(by=['class', 'sex'])[['Tensorflow', 'Keras']].agg([\"max\", \"min\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "04c97251-93f2-4028-b9db-2f5c987f9e62",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr:last-of-type th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th colspan=\"2\" halign=\"left\">Python</th>\n",
       "      <th colspan=\"2\" halign=\"left\">Tensorflow</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>最大值</th>\n",
       "      <th>最小值</th>\n",
       "      <th>计数</th>\n",
       "      <th>中位数</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>class</th>\n",
       "      <th>sex</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">1</th>\n",
       "      <th>女</th>\n",
       "      <td>148</td>\n",
       "      <td>38</td>\n",
       "      <td>23</td>\n",
       "      <td>63.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>145</td>\n",
       "      <td>2</td>\n",
       "      <td>22</td>\n",
       "      <td>100.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">2</th>\n",
       "      <th>女</th>\n",
       "      <td>145</td>\n",
       "      <td>9</td>\n",
       "      <td>16</td>\n",
       "      <td>82.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>147</td>\n",
       "      <td>1</td>\n",
       "      <td>16</td>\n",
       "      <td>63.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">3</th>\n",
       "      <th>女</th>\n",
       "      <td>144</td>\n",
       "      <td>1</td>\n",
       "      <td>21</td>\n",
       "      <td>74.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>146</td>\n",
       "      <td>9</td>\n",
       "      <td>13</td>\n",
       "      <td>76.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">4</th>\n",
       "      <th>女</th>\n",
       "      <td>148</td>\n",
       "      <td>4</td>\n",
       "      <td>14</td>\n",
       "      <td>62.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>148</td>\n",
       "      <td>11</td>\n",
       "      <td>24</td>\n",
       "      <td>95.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">5</th>\n",
       "      <th>女</th>\n",
       "      <td>144</td>\n",
       "      <td>2</td>\n",
       "      <td>17</td>\n",
       "      <td>93.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>144</td>\n",
       "      <td>3</td>\n",
       "      <td>12</td>\n",
       "      <td>78.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">6</th>\n",
       "      <th>女</th>\n",
       "      <td>150</td>\n",
       "      <td>4</td>\n",
       "      <td>23</td>\n",
       "      <td>87.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>142</td>\n",
       "      <td>3</td>\n",
       "      <td>23</td>\n",
       "      <td>75.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">7</th>\n",
       "      <th>女</th>\n",
       "      <td>139</td>\n",
       "      <td>2</td>\n",
       "      <td>22</td>\n",
       "      <td>83.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>150</td>\n",
       "      <td>13</td>\n",
       "      <td>17</td>\n",
       "      <td>78.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">8</th>\n",
       "      <th>女</th>\n",
       "      <td>147</td>\n",
       "      <td>3</td>\n",
       "      <td>22</td>\n",
       "      <td>76.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>男</th>\n",
       "      <td>141</td>\n",
       "      <td>4</td>\n",
       "      <td>15</td>\n",
       "      <td>70.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          Python     Tensorflow       \n",
       "             最大值 最小值         计数    中位数\n",
       "class sex                             \n",
       "1     女      148  38         23   63.0\n",
       "      男      145   2         22  100.5\n",
       "2     女      145   9         16   82.0\n",
       "      男      147   1         16   63.5\n",
       "3     女      144   1         21   74.0\n",
       "      男      146   9         13   76.0\n",
       "4     女      148   4         14   62.0\n",
       "      男      148  11         24   95.5\n",
       "5     女      144   2         17   93.0\n",
       "      男      144   3         12   78.0\n",
       "6     女      150   4         23   87.0\n",
       "      男      142   3         23   75.0\n",
       "7     女      139   2         22   83.0\n",
       "      男      150  13         17   78.0\n",
       "8     女      147   3         22   76.5\n",
       "      男      141   4         15   70.0"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 分组后不同属性应用多种不同统计汇总\n",
    "df.groupby(by=['class', 'sex'])[['Python', 'Tensorflow']].agg(\n",
    "    {\n",
    "        'Python': [('最大值', 'max'), ('最小值', 'min')],\n",
    "        'Tensorflow': [('计数', 'count'), ('中位数', 'median')]\n",
    "    }\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "71fd93dc-ff36-4e22-a852-8b3a17a72e5a",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
